// ScFuzDll.cpp : Defines the entry point for the DLL application.
//

/*
WinSCard.dll Exports (Vista)
          1    0 000031B1 ClassInstall32
          2    1 000068A8 SCardAccessNewReaderEvent
          5    2 00002942 SCardAccessStartedEvent
          6    3 000089DF SCardAddReaderToGroupA
          7    4 0000A1B5 SCardAddReaderToGroupW
          8    5 00007466 SCardBeginTransaction
          9    6 00007328 SCardCancel
         10    7 00009030 SCardConnectA
         11    8 0000A806 SCardConnectW
         12    9 0000783E SCardControl
         13    A 00006DD4 SCardDisconnect
         14    B 000074F5 SCardEndTransaction
         15    C 00003800 SCardEstablishContext
         16    D 00008D82 SCardForgetCardTypeA
         17    E 0000A558 SCardForgetCardTypeW
         18    F 000088F4 SCardForgetReaderA
         19   10 000086EF SCardForgetReaderGroupA
         20   11 00009EC5 SCardForgetReaderGroupW
         21   12 0000A0CA SCardForgetReaderW
         22   13 00006F35 SCardFreeMemory
         23   14 00007929 SCardGetAttrib
         24   15 00008525 SCardGetCardTypeProviderNameA
         25   16 00009CFB SCardGetCardTypeProviderNameW
         26   17 0000841E SCardGetProviderIdA
         27   18 00009BF4 SCardGetProviderIdW
         28   19 00008F11 SCardGetStatusChangeA
         29   1A 0000A6E7 SCardGetStatusChangeW
         30   1B 000077AC SCardGetTransmitCount
         31   1C 00008C13 SCardIntroduceCardTypeA
         32   1D 0000A3E9 SCardIntroduceCardTypeW
         33   1E 000087DA SCardIntroduceReaderA
         34   1F 00008604 SCardIntroduceReaderGroupA
         35   20 00009DDA SCardIntroduceReaderGroupW
         36   21 00009FB0 SCardIntroduceReaderW
         37   22 00006E78 SCardIsValidContext
         38   23 0000825D SCardListCardsA
         39   24 00009A33 SCardListCardsW
         40   25 0000830D SCardListInterfacesA
         41   26 00009AE3 SCardListInterfacesW
         42   27 00008008 SCardListReaderGroupsA
         43   28 000097DE SCardListReaderGroupsW
         44   29 00008112 SCardListReadersA
         45   2A 000098E8 SCardListReadersW
         46   2B 0000935D SCardLocateCardsA
         47   2C 00008E19 SCardLocateCardsByATRA
         48   2D 0000A5EF SCardLocateCardsByATRW
         49   2E 0000AB33 SCardLocateCardsW
         50   2F 00007DD3 SCardReadCacheA
         51   30 00009593 SCardReadCacheW
         52   31 000073B4 SCardReconnect
          3   32 000068C9 SCardReleaseAllEvents
         53   33 00006D1B SCardReleaseContext
          4   34 000068BF SCardReleaseNewReaderEvent
         54   35 000068B2 SCardReleaseStartedEvent
         55   36 00008AF9 SCardRemoveReaderFromGroupA
         56   37 0000A2CF SCardRemoveReaderFromGroupW
         57   38 00007D14 SCardSetAttrib
         58   39 00008CBC SCardSetCardTypeProviderNameA
         59   3A 0000A492 SCardSetCardTypeProviderNameW
         60   3B 00007587 SCardState
         61   3C 00009218 SCardStatusA
         62   3D 0000A9EE SCardStatusW
         63   3E 000076AB SCardTransmit
         64   3F 00007DAC SCardWriteCacheA
         65   40 0000956C SCardWriteCacheW
         66   41 00001DD4 g_rgSCardRawPci
         67   42 00001DC4 g_rgSCardT0Pci
         68   43 00001DCC g_rgSCardT1Pci

BaseCSP.dll Imports from WinSCard.dll (Vista)
                    C SCardEstablishContext
                    8 SCardConnectW
                   24 SCardListCardsW
                   1A SCardGetStatusChangeW
                   2A SCardListReadersW
                    B SCardEndTransaction
                   3D SCardStatusW
                   31 SCardReconnect
                    5 SCardBeginTransaction
                    6 SCardCancel
                    A SCardDisconnect
                   33 SCardReleaseContext
                   13 SCardFreeMemory
                   16 SCardGetCardTypeProviderNameW

AxaltoCM.dll Imports from WinSCard.dll (Vista)
      6CB7A3E9     1D SCardIntroduceCardTypeW
      6CB7A558      E SCardForgetCardTypeW
      6CB76D1B     33 SCardReleaseContext
      6CB776AB     3E SCardTransmit
      6CB71DC4     42 g_rgSCardT0Pci
      6CB7A806      8 SCardConnectW
      6CB73800      C SCardEstablishContext
      6CB76DD4      A SCardDisconnect
      6CB76F35     13 SCardFreeMemory
      6CB7A6E7     1A SCardGetStatusChangeW
      6CB798E8     2A SCardListReadersW
      6CB7A492     3A SCardSetCardTypeProviderNameW
*/

#include "stdafx.h"

#ifdef _MANAGED
#pragma managed(push, off)
#endif

//
// Flow macros
//

static 
void
WINAPI
_OutputDbgStr(
    __in  LPSTR szMsg,
    __in  DWORD dwStatus)
{
    CHAR rgsz [256];

    StringCbPrintfA(
        rgsz,
        sizeof(rgsz),
        "ERROR: %s - 0x%x\n",
        szMsg,
        dwStatus);
    OutputDebugStringA(rgsz);
}

#define TRY_DWORD(_X) {                                             \
    if (ERROR_SUCCESS != (status = _X)) {                           \
        _OutputDbgStr(#_X, status);                                 \
        __leave;                                                    \
    }                                                               \
}

#define TRY_BOOL(_X) {                                              \
    if (FALSE == (_X)) {                                            \
        status = GetLastError();                                    \
        _OutputDbgStr(#_X, status);                                 \
        __leave;                                                    \
    }                                                               \
}

#define TRY_PTR(_X) {                                               \
    if (NULL == (_X)) {                                             \
        status = GetLastError();                                    \
        _OutputDbgStr(#_X, status);                                 \
        __leave;                                                    \
    }                                                               \
}

#define TRY_ALLOC(_X) {                                             \
    if (NULL == (_X)) {                                             \
        status = ERROR_NOT_ENOUGH_MEMORY;                           \
        __leave;                                                    \
    }                                                               \
}

// 
// Context structure information
// 

typedef LONG (WINAPI *PFN_SCARDBEGINTRANSACTION)(
    IN      SCARDHANDLE hCard);

typedef LONG (WINAPI *PFN_SCARDCANCEL)(
    IN      SCARDCONTEXT hContext);

typedef LONG (WINAPI *PFN_SCARDCONNECTW)(
    IN      SCARDCONTEXT hContext,
    IN      LPCWSTR szReader,
    IN      DWORD dwShareMode,
    IN      DWORD dwPreferredProtocols,
    OUT     LPSCARDHANDLE phCard,
    OUT     LPDWORD pdwActiveProtocol);

typedef LONG (WINAPI *PFN_SCARDDISCONNECT)(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwDisposition);

typedef LONG (WINAPI *PFN_SCARDENDTRANSACTION)(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwDisposition);

typedef LONG (WINAPI *PFN_SCARDESTABLISHCONTEXT)(
    IN  DWORD dwScope,
    IN  LPCVOID pvReserved1,
    IN  LPCVOID pvReserved2,
    OUT LPSCARDCONTEXT phContext);

typedef LONG (WINAPI *PFN_SCARDFORGETCARDTYPEW)(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName);

typedef LONG (WINAPI *PFN_SCARDFREEMEMORY)(
    IN SCARDCONTEXT hContext,
    IN LPCVOID pvMem);

typedef LONG (WINAPI *PFN_SCARDGETCARDTYPEPROVIDERNAMEW)(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName,
    IN DWORD dwProviderId,
    OUT LPWSTR szProvider,
    IN OUT LPDWORD pcchProvider);

typedef LONG (WINAPI *PFN_SCARDGETSTATUSCHANGEW)(
    IN      SCARDCONTEXT hContext,
    IN      DWORD dwTimeout,
    IN OUT  LPSCARD_READERSTATEW rgReaderStates,
    IN      DWORD cReaders);

typedef LONG (WINAPI *PFN_SCARDINTRODUCECARDTYPEW)(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName,
    IN LPCGUID pguidPrimaryProvider,
    IN LPCGUID rgguidInterfaces,
    IN DWORD dwInterfaceCount,
    IN LPCBYTE pbAtr,
    IN LPCBYTE pbAtrMask,
    IN DWORD cbAtrLen);

typedef LONG (WINAPI *PFN_SCARDLISTCARDSW)(
    IN      SCARDCONTEXT hContext,
    IN      LPCBYTE pbAtr,
    IN      LPCGUID rgquidInterfaces,
    IN      DWORD cguidInterfaceCount,
    OUT     LPWSTR mszCards,
    IN OUT  LPDWORD pcchCards);

typedef LONG (WINAPI *PFN_SCARDLISTREADERSW)(
    IN      SCARDCONTEXT hContext,
    IN      LPCWSTR mszGroups,
    OUT     LPWSTR mszReaders,
    IN OUT  LPDWORD pcchReaders);

typedef LONG (WINAPI *PFN_SCARDRECONNECT)(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwShareMode,
    IN      DWORD dwPreferredProtocols,
    IN      DWORD dwInitialization,
    OUT     LPDWORD pdwActiveProtocol);

typedef LONG (WINAPI *PFN_SCARDRELEASECONTEXT)(
    IN      SCARDCONTEXT hContext);

typedef LONG (WINAPI *PFN_SCARDSTATUSW)(
    IN SCARDHANDLE hCard,
    OUT LPWSTR szReaderName,
    IN OUT LPDWORD pcchReaderLen,
    OUT LPDWORD pdwState,
    OUT LPDWORD pdwProtocol,
    OUT LPBYTE pbAtr,
    IN OUT LPDWORD pcbAtrLen);

typedef LONG (WINAPI *PFN_SCARDTRANSMIT)(
    IN SCARDHANDLE hCard,
    IN LPCSCARD_IO_REQUEST pioSendPci,
    IN LPCBYTE pbSendBuffer,
    IN DWORD cbSendLength,
    IN OUT LPSCARD_IO_REQUEST pioRecvPci,
    OUT LPBYTE pbRecvBuffer,
    IN OUT LPDWORD pcbRecvLength);

typedef struct _SCFUZ_CTX
{
    HMODULE hWinSCard;
    PFN_SCARDBEGINTRANSACTION pfnSCardBeginTransaction;
    PFN_SCARDCANCEL pfnSCardCancel;
    PFN_SCARDCONNECTW pfnSCardConnect;
    PFN_SCARDDISCONNECT pfnSCardDisconnect;
    PFN_SCARDENDTRANSACTION pfnSCardEndTransaction;
    PFN_SCARDESTABLISHCONTEXT pfnSCardEstablishContext;
    PFN_SCARDFORGETCARDTYPEW pfnSCardForgetCardTypeW;
    PFN_SCARDFREEMEMORY pfnSCardFreeMemory;
    PFN_SCARDGETCARDTYPEPROVIDERNAMEW pfnSCardGetCardTypeProviderNameW;
    PFN_SCARDGETSTATUSCHANGEW pfnSCardGetStatusChangeW;
    PFN_SCARDINTRODUCECARDTYPEW pfnSCardIntroduceCardTypeW;
    PFN_SCARDLISTCARDSW pfnSCardListCardsW;
    PFN_SCARDLISTREADERSW pfnSCardListReadersW;
    PFN_SCARDRECONNECT pfnSCardReconnect;
    PFN_SCARDRELEASECONTEXT pfnSCardReleaseContext;
    PFN_SCARDSTATUSW pfnSCardStatusW;
    PFN_SCARDTRANSMIT pfnSCardTransmit;
} SCFUZ_CTX, *PSCFUZ_CTX;

//
// Initialize the context structure
// 
DWORD
WINAPI
_ScFuzCtxInitialize(
    __inout             PSCFUZ_CTX pCtx)
{
    DWORD status = ERROR_SUCCESS;

    //
    // Load winscard
    // 

    TRY_PTR(pCtx->hWinSCard = LoadLibraryExA("winscard.dll", NULL, 0));

    //
    // Get all of the export addresses
    // 

    // TODO

    PFN_SCARDBEGINTRANSACTION pfnSCardBeginTransaction;
    PFN_SCARDCANCEL pfnSCardCancel;
    PFN_SCARDCONNECTW pfnSCardConnect;
    PFN_SCARDDISCONNECT pfnSCardDisconnect;
    PFN_SCARDENDTRANSACTION pfnSCardEndTransaction;
    PFN_SCARDESTABLISHCONTEXT pfnSCardEstablishContext;
    PFN_SCARDFORGETCARDTYPEW pfnSCardForgetCardTypeW;
    PFN_SCARDFREEMEMORY pfnSCardFreeMemory;
    PFN_SCARDGETCARDTYPEPROVIDERNAMEW pfnSCardGetCardTypeProviderNameW;
    PFN_SCARDGETSTATUSCHANGEW pfnSCardGetStatusChangeW;
    PFN_SCARDINTRODUCECARDTYPEW pfnSCardIntroduceCardTypeW;
    PFN_SCARDLISTCARDSW pfnSCardListCardsW;
    PFN_SCARDLISTREADERSW pfnSCardListReadersW;
    PFN_SCARDRECONNECT pfnSCardReconnect;
    PFN_SCARDRELEASECONTEXT pfnSCardReleaseContext;
    PFN_SCARDSTATUSW pfnSCardStatusW;
    PFN_SCARDTRANSMIT pfnSCardTransmit;


}

//
// Cleanup the context structure
// 
void
WINAPI
_ScFuzCtxCleanup(
    __inout             PSCFUZ_CTX pCtx)
{
    if (NULL != pCtx->hWinSCard)
    {
        FreeLibrary(pCtx->hWinSCard);
        pCtx->hWinSCard = NULL;
    }
}

//
// Helper routines
// 

DWORD
WINAPI
_Initialize(void)
{

}

//
// Dll Exports
// 

/*
Still need to export:
      6CB71DC4     42 g_rgSCardT0Pci
*/

LONG 
WINAPI
SCardBeginTransaction(
    IN      SCARDHANDLE hCard)
{
    REDIRECT(pfnSCardBeginTransaction(hCard));
}

LONG 
WINAPI
SCardCancel(
    IN      SCARDCONTEXT hContext);

LONG 
WINAPI
SCardConnectW(
    IN      SCARDCONTEXT hContext,
    IN      LPCWSTR szReader,
    IN      DWORD dwShareMode,
    IN      DWORD dwPreferredProtocols,
    OUT     LPSCARDHANDLE phCard,
    OUT     LPDWORD pdwActiveProtocol);

LONG 
WINAPI
SCardDisconnect(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwDisposition);

LONG 
WINAPI
SCardEndTransaction(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwDisposition);

LONG 
WINAPI
SCardEstablishContext(
    IN  DWORD dwScope,
    IN  LPCVOID pvReserved1,
    IN  LPCVOID pvReserved2,
    OUT LPSCARDCONTEXT phContext);

LONG 
WINAPI
SCardForgetCardTypeW(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName);

LONG 
WINAPI
SCardFreeMemory(
    IN SCARDCONTEXT hContext,
    IN LPCVOID pvMem);

LONG 
WINAPI
SCardGetCardTypeProviderNameW(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName,
    IN DWORD dwProviderId,
    OUT LPWSTR szProvider,
    IN OUT LPDWORD pcchProvider);

LONG 
WINAPI
SCardGetStatusChangeW(
    IN      SCARDCONTEXT hContext,
    IN      DWORD dwTimeout,
    IN OUT  LPSCARD_READERSTATEW rgReaderStates,
    IN      DWORD cReaders);

LONG 
WINAPI
SCardIntroduceCardTypeW(
    IN SCARDCONTEXT hContext,
    IN LPCWSTR szCardName,
    IN LPCGUID pguidPrimaryProvider,
    IN LPCGUID rgguidInterfaces,
    IN DWORD dwInterfaceCount,
    IN LPCBYTE pbAtr,
    IN LPCBYTE pbAtrMask,
    IN DWORD cbAtrLen);

LONG 
WINAPI
SCardListCardsW(
    IN      SCARDCONTEXT hContext,
    IN      LPCBYTE pbAtr,
    IN      LPCGUID rgquidInterfaces,
    IN      DWORD cguidInterfaceCount,
    OUT     LPWSTR mszCards,
    IN OUT  LPDWORD pcchCards);

LONG 
WINAPI
SCardListReadersW(
    IN      SCARDCONTEXT hContext,
    IN      LPCWSTR mszGroups,
    OUT     LPWSTR mszReaders,
    IN OUT  LPDWORD pcchReaders);

LONG 
WINAPI
SCardReconnect(
    IN      SCARDHANDLE hCard,
    IN      DWORD dwShareMode,
    IN      DWORD dwPreferredProtocols,
    IN      DWORD dwInitialization,
    OUT     LPDWORD pdwActiveProtocol);

LONG 
WINAPI
SCardReleaseContext(
    IN      SCARDCONTEXT hContext);

LONG 
WINAPI
SCardStatusW(
    IN SCARDHANDLE hCard,
    OUT LPWSTR szReaderName,
    IN OUT LPDWORD pcchReaderLen,
    OUT LPDWORD pdwState,
    OUT LPDWORD pdwProtocol,
    OUT LPBYTE pbAtr,
    IN OUT LPDWORD pcbAtrLen);

LONG 
WINAPI
SCardTransmit(
    IN SCARDHANDLE hCard,
    IN LPCSCARD_IO_REQUEST pioSendPci,
    IN LPCBYTE pbSendBuffer,
    IN DWORD cbSendLength,
    IN OUT LPSCARD_IO_REQUEST pioRecvPci,
    OUT LPBYTE pbRecvBuffer,
    IN OUT LPDWORD pcbRecvLength);

//
// Main Dll entry point
// 
BOOL APIENTRY DllMain( HMODULE hModule,
                       DWORD  ul_reason_for_call,
                       LPVOID lpReserved
					 )
{
    return TRUE;
}

#ifdef _MANAGED
#pragma managed(pop)
#endif

